home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / rzsz0593.zip / RBSB.C < prev    next >
C/C++ Source or Header  |  1993-05-05  |  10KB  |  539 lines

  1. /*
  2.  *    V7/BSD HACKERS:  SEE NOTES UNDER mode(2) !!!
  3.  *
  4.  *   This file is #included so the main file can set parameters such as HOWMANY.
  5.  *   See the main files (rz.c/sz.c) for compile instructions.
  6.  */
  7.  
  8. char *Copyr = "Copyright 1993 Omen Technology Inc All Rights Reserved";
  9.  
  10. #ifdef V7
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #define STAT
  14. #include <sgtty.h>
  15. #define OS "V7/BSD"
  16. #ifdef LLITOUT
  17. long Locmode;        /* Saved "local mode" for 4.x BSD "new driver" */
  18. long Locbit = LLITOUT;    /* Bit SUPPOSED to disable output translations */
  19. #include <strings.h>
  20. #endif
  21. #endif
  22.  
  23. #ifdef USG
  24. #include <sys/types.h>
  25. #include <sys/stat.h>
  26. #define STAT
  27. #include <termio.h>
  28. #define OS "SYS III/V"
  29. #define MODE2OK
  30. #include <string.h>
  31. #endif
  32.  
  33. #ifdef POSIX
  34. #define USG
  35. #include <sys/types.h>
  36. #include <sys/stat.h>
  37. #include <sys/ioctl.h>
  38. #define STAT
  39. #include <termios.h>
  40. #define OS "POSIX"
  41. #include <string.h>
  42. #ifndef READCHECK
  43. #ifndef FIONREAD
  44. #define SV
  45. #endif
  46. #endif
  47. #endif
  48.  
  49.  
  50. #ifdef T6K
  51. #include <sys/ioctl.h>        /* JPRadley: for the Tandy 6000 */
  52. #endif
  53.  
  54. #include <setjmp.h>
  55.  
  56. #if HOWMANY  > 255
  57. Howmany must be 255 or less
  58. #endif
  59.  
  60.  /*
  61.  *  Some systems (Venix, Coherent, Regulus) may not support tty raw mode
  62.  *  read(2) the same way as Unix. ONEREAD must be defined to force one
  63.  *  character reads for these systems. Added 7-01-84 CAF
  64.  */
  65.  
  66. #define sendline(c) putc(c & 0377, Ttystream)
  67. #define xsendline(c) putc(c, Ttystream)
  68.  
  69. FILE *Ttystream;
  70. int Tty;
  71. char linbuf[HOWMANY];
  72. char xXbuf[BUFSIZ];
  73. int Lleft=0;        /* number of characters in linbuf */
  74. jmp_buf tohere;        /* For the interrupt on RX timeout */
  75. #ifdef ONEREAD
  76. /* Sorry, Regulus and some others don't work right in raw mode! */
  77. int Readnum = 1;    /* Number of bytes to ask for in read() from modem */
  78. #else
  79. int Readnum = HOWMANY;    /* Number of bytes to ask for in read() from modem */
  80. #endif
  81. int Verbose=0;
  82.  
  83.  
  84. int Twostop;        /* Use two stop bits */
  85.  
  86.  
  87. /*
  88.  *  The following uses an external rdchk() routine if available,
  89.  *  otherwise defines the function for BSD or fakes it for SYSV.
  90.  */
  91.  
  92. #ifndef READCHECK
  93. #ifdef FIONREAD
  94. #define READCHECK
  95. /*
  96.  *  Return non 0 iff something to read from io descriptor f
  97.  */
  98. rdchk(f)
  99. {
  100.     static long lf;
  101.  
  102.     ioctl(f, FIONREAD, &lf);
  103.     return ((int) lf);
  104. }
  105.  
  106. #else        /* FIONREAD */
  107.  
  108. #ifdef SV
  109. #define READCHECK
  110. #include <fcntl.h>
  111.  
  112. int checked = 0;
  113. /*
  114.  * Nonblocking I/O is a bit different in System V, Release 2
  115.  *  Note: this rdchk vsn throws away a byte, OK for ZMODEM
  116.  *  sender because protocol design anticipates this problem.
  117.  */
  118. #define EATSIT
  119. rdchk(f)
  120. {
  121.     int lf, savestat;
  122.     static char bchecked;
  123.  
  124.     savestat = fcntl(f, F_GETFL) ;
  125.     fcntl(f, F_SETFL, savestat | O_NONBLOCK) ;
  126.     lf = read(f, &bchecked, 1) ;
  127.     fcntl(f, F_SETFL, savestat) ;
  128.     checked = bchecked & 0377;    /* force unsigned byte */
  129.     return(lf) ;
  130. }
  131. #endif
  132. #endif
  133. #endif
  134.  
  135.  
  136. struct {
  137.     unsigned baudr;
  138.     int speedcode;
  139. } speeds[] = {
  140.     110,    B110,
  141. #ifdef B150
  142.     150,    B150,
  143. #endif
  144.     300,    B300,
  145.     600,    B600,
  146.     1200,    B1200,
  147.     2400,    B2400,
  148.     4800,    B4800,
  149.     9600,    B9600,
  150. #ifdef B19200
  151.     19200,    B19200,
  152. #endif
  153. #ifdef EXTA
  154.     19200,    EXTA,
  155. #endif
  156. #ifdef B38400
  157.     38400,    B38400,
  158. #endif
  159. #ifdef EXTB
  160.     38400,    EXTB,
  161. #endif
  162.     0,    0
  163. };
  164. static unsigned
  165. getspeed(code)
  166. {
  167.     register n;
  168.  
  169.     for (n=0; speeds[n].baudr; ++n)
  170.         if (speeds[n].speedcode == code)
  171.             return speeds[n].baudr;
  172.     if (code > 49)
  173.         return ((unsigned)code);
  174.     return 1;    /* Assume fifo if ioctl failed */
  175. }
  176.  
  177.  
  178.  
  179.  
  180. #ifdef ICANON
  181. #ifdef POSIX
  182. struct termios oldtty, tty;
  183. #else
  184. struct termio oldtty, tty;
  185. #endif
  186. #else
  187. struct sgttyb oldtty, tty;
  188. struct tchars oldtch, tch;
  189. #endif
  190.  
  191. /*
  192.  * mode(n)
  193.  *  3: save old tty stat, set raw mode with flow control
  194.  *  2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
  195.  *  1: save old tty stat, set raw mode 
  196.  *  0: restore original tty mode
  197.  */
  198. mode(n)
  199. {
  200.     static did0 = FALSE;
  201.  
  202.     vfile("mode:%d", n);
  203.     switch(n) {
  204. #ifdef USG
  205.     case 2:        /* Un-raw mode used by sz, sb when -g detected */
  206. #ifdef POSIX
  207.         if(!did0)
  208.             (void) tcgetattr(Tty, &oldtty);
  209. #else
  210.         if(!did0)
  211.             (void) ioctl(Tty, TCGETA, &oldtty);
  212. #endif
  213.         tty = oldtty;
  214.  
  215.         tty.c_iflag = BRKINT|IXON;
  216.  
  217.         tty.c_oflag = 0;    /* Transparent output */
  218.  
  219.         tty.c_cflag &= ~(PARENB|CSIZE);        /* Disable parity */
  220.         tty.c_cflag |= (CREAD|CS8);    /* Set character size = 8 */
  221.         if (Twostop)
  222.             tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  223.  
  224.  
  225. #ifdef READCHECK
  226.         tty.c_lflag = Zmodem ? 0 : ISIG;
  227.         tty.c_cc[VINTR] = Zmodem ? -1:030;    /* Interrupt char */
  228. #else
  229.         tty.c_lflag = ISIG;
  230.         tty.c_cc[VINTR] = Zmodem ? 03:030;    /* Interrupt char */
  231. #endif
  232.         tty.c_cc[VQUIT] = -1;            /* Quit char */
  233. #ifdef NFGVMIN
  234.         tty.c_cc[VMIN] = 1;
  235. #else
  236.         tty.c_cc[VMIN] = 3;     /* This many chars satisfies reads */
  237. #endif
  238.         tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  239.  
  240. #ifdef POSIX
  241.         (void) tcsetattr(Tty, TCSADRAIN, &tty);
  242. #else
  243.         (void) ioctl(Tty, TCSETAW, &tty);
  244. #endif
  245.         did0 = TRUE;
  246.         return OK;
  247.     case 1:
  248.     case 3:
  249. #ifdef POSIX
  250.         if(!did0)
  251.             (void) tcgetattr(Tty, &oldtty);
  252. #else
  253.         if(!did0)
  254.             (void) ioctl(Tty, TCGETA, &oldtty);
  255. #endif
  256.         tty = oldtty;
  257.  
  258.         tty.c_iflag = n==3 ? (IXON|IXOFF) : IXOFF;
  259.  
  260.         tty.c_lflag = 0;
  261.  
  262.         tty.c_oflag = 0;
  263.  
  264.         tty.c_cflag &= ~(CSIZE|PARENB);    /* disable parity */
  265.         tty.c_cflag |= CS8;    /* Set character size = 8 */
  266.         if (Twostop)
  267.             tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  268. #ifdef NFGVMIN
  269.         tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
  270. #else
  271.         tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
  272. #endif
  273.         tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  274. #ifdef POSIX
  275.         (void) tcsetattr(Tty, TCSADRAIN, &tty);
  276. #else
  277.         (void) ioctl(Tty, TCSETAW, &tty);
  278. #endif
  279.         did0 = TRUE;
  280. #ifdef POSIX
  281.         Effbaud = Baudrate = getspeed(cfgetospeed(&tty));
  282. #else
  283.         Effbaud = Baudrate = getspeed(tty.c_cflag & CBAUD);
  284. #endif
  285.         vfile("Baudrate = %u\n", Baudrate);
  286.         return OK;
  287. #endif
  288. #ifdef V7
  289.     /*
  290.      *  NOTE: this should transmit all 8 bits and at the same time
  291.      *   respond to XOFF/XON flow control.  If no FIONREAD or other
  292.      *   rdchk() alternative, also must respond to INTRRUPT char
  293.      *   This doesn't work with V7.  It should work with LLITOUT,
  294.      *   but LLITOUT was broken on the machine I tried it on.
  295.      */
  296.     case 2:        /* Un-raw mode used by sz, sb when -g detected */
  297.         if(!did0) {
  298.             ioctl(Tty, TIOCEXCL, 0);
  299.             ioctl(Tty, TIOCGETP, &oldtty);
  300.             ioctl(Tty, TIOCGETC, &oldtch);
  301. #ifdef LLITOUT
  302.             ioctl(Tty, TIOCLGET, &Locmode);
  303. #endif
  304.         }
  305.         tty = oldtty;
  306.         tch = oldtch;
  307. #ifdef READCHECK
  308.         tch.t_intrc = Zmodem ? -1:030;    /* Interrupt char */
  309. #else
  310.         tch.t_intrc = Zmodem ? 03:030;    /* Interrupt char */
  311. #endif
  312.         tty.sg_flags |= (ODDP|EVENP|CBREAK);
  313.         tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);
  314.         ioctl(Tty, TIOCSETP, &tty);
  315.         ioctl(Tty, TIOCSETC, &tch);
  316. #ifdef LLITOUT
  317.         ioctl(Tty, TIOCLBIS, &Locbit);
  318. #else
  319.         bibi(99);    /* un-raw doesn't work w/o lit out */
  320. #endif
  321.         did0 = TRUE;
  322.         return OK;
  323.     case 1:
  324.     case 3:
  325.         if(!did0) {
  326.             ioctl(Tty, TIOCEXCL, 0);
  327.             ioctl(Tty, TIOCGETP, &oldtty);
  328.             ioctl(Tty, TIOCGETC, &oldtch);
  329. #ifdef LLITOUT
  330.             ioctl(Tty, TIOCLGET, &Locmode);
  331. #endif
  332.         }
  333.         tty = oldtty;
  334.         tty.sg_flags |= (RAW|TANDEM);
  335.         tty.sg_flags &= ~ECHO;
  336.         ioctl(Tty, TIOCSETP, &tty);
  337.         did0 = TRUE;
  338.         Effbaud = Baudrate = getspeed(tty.sg_ospeed);
  339.         return OK;
  340. #endif
  341.     case 0:
  342.         if(!did0)
  343.             return ERROR;
  344. #ifdef USG
  345. #ifdef POSIX
  346.         (void) tcdrain(Tty);    /* Wait for output to drain */
  347.         (void) tcflush(Tty, TCIFLUSH);    /* Flush input queue */
  348.         (void) tcsetattr(Tty, TCSADRAIN, &oldtty);    /* Restore */
  349.         (void) tcflow(Tty, TCOON);    /* Restart output */
  350. #else
  351.         (void) ioctl(Tty, TCSBRK, 1);    /* Wait for output to drain */
  352.         (void) ioctl(Tty, TCFLSH, 1);    /* Flush input queue */
  353.         (void) ioctl(Tty, TCSETAW, &oldtty);    /* Restore modes */
  354.         (void) ioctl(Tty, TCXONC,1);    /* Restart output */
  355. #endif
  356. #endif
  357. #ifdef V7
  358.         ioctl(Tty, TIOCSETP, &oldtty);
  359.         ioctl(Tty, TIOCSETC, &oldtch);
  360.         ioctl(Tty, TIOCNXCL, 0);
  361. #ifdef LLITOUT
  362.         ioctl(Tty, TIOCLSET, &Locmode);
  363. #endif
  364. #endif
  365.  
  366.         return OK;
  367.     default:
  368.         return ERROR;
  369.     }
  370. }
  371.  
  372. sendbrk()
  373. {
  374. #ifdef V7
  375. #ifdef TIOCSBRK
  376. #define CANBREAK
  377.     sleep(1);
  378.     ioctl(Tty, TIOCSBRK, 0);
  379.     sleep(1);
  380.     ioctl(Tty, TIOCCBRK, 0);
  381. #endif
  382. #endif
  383. #ifdef USG
  384. #define CANBREAK
  385. #ifdef POSIX
  386.     tcsendbreak(Tty, 200);
  387. #else
  388.     ioctl(Tty, TCSBRK, 0);
  389. #endif
  390. #endif
  391. }
  392.  
  393. /* Initialize tty device for serial file xfer */
  394. inittty()
  395. {
  396.     Tty = open("/dev/tty", 2);
  397.     if (Tty < 0) {
  398.         perror("/dev/tty");  exit(2);
  399.     }
  400.     Ttystream = fdopen(Tty, "w");
  401. /*
  402.     setbuf(Ttystream, xXbuf);        
  403. */
  404. }
  405.  
  406. flushmoc()
  407. {
  408.     fflush(Ttystream);
  409. }
  410. flushmo()
  411. {
  412.     fflush(Ttystream);
  413. }
  414.  
  415. /*
  416.  * This version of readline is reasoably well suited for
  417.  * reading many characters.
  418.  *
  419.  * timeout is in tenths of seconds
  420.  */
  421. void
  422. alrm(c)
  423. {
  424.     longjmp(tohere, -1);
  425. }
  426. readline(timeout)
  427. int timeout;
  428. {
  429.     register n;
  430.     static char *cdq;    /* pointer for removing chars from linbuf */
  431.  
  432.     if (--Lleft >= 0) {
  433.         if (Verbose > 8) {
  434.             fprintf(stderr, "%02x ", *cdq&0377);
  435.         }
  436.         return (*cdq++ & 0377);
  437.     }
  438.     n = timeout/10;
  439.     if (n < 2)
  440.         n = 2;
  441.     if (Verbose > 5)
  442.         fprintf(stderr, "Calling read: alarm=%d  Readnum=%d ",
  443.           n, Readnum);
  444.     if (setjmp(tohere)) {
  445. #ifdef TIOCFLUSH
  446. /*        ioctl(Tty, TIOCFLUSH, 0); */
  447. #endif
  448.         Lleft = 0;
  449.         if (Verbose>1)
  450.             fprintf(stderr, "Readline:TIMEOUT\n");
  451.         return TIMEOUT;
  452.     }
  453.     signal(SIGALRM, alrm); alarm(n);
  454.     errno = 0;
  455.     Lleft=read(Tty, cdq=linbuf, Readnum);
  456.     alarm(0);
  457.     if (Verbose > 5) {
  458.         fprintf(stderr, "Read returned %d bytes errno=%d\n",
  459.           Lleft, errno);
  460.     }
  461.     if (Lleft < 1)
  462.         return TIMEOUT;
  463.     if (Verbose > 8) {
  464.         for (n = Lleft; --n >= 0; ) {
  465.             fprintf(stderr, "%02x ", *cdq&0377);
  466.         }
  467.         fprintf(stderr, "\n");
  468.     }
  469.     --Lleft;
  470.     return (*cdq++ & 0377);
  471. }
  472.  
  473.  
  474.  
  475. /*
  476.  * Purge the modem input queue of all characters
  477.  */
  478. purgeline()
  479. {
  480.     Lleft = 0;
  481. #ifdef USG
  482. #ifdef POSIX
  483.     tcflush(Tty, 0);
  484. #else
  485.     ioctl(Tty, TCFLSH, 0);
  486. #endif
  487. #else
  488.     lseek(Tty, 0L, 2);
  489. #endif
  490. }
  491.  
  492.  
  493. /* send cancel string to get the other end to shut up */
  494. canit()
  495. {
  496.     static char canistr[] = {
  497.      24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
  498.     };
  499.  
  500.     zmputs(canistr);
  501.     Lleft=0;    /* Do read next time ... */
  502. }
  503.  
  504. /*
  505.  * Send a string to the modem, processing for \336 (sleep 1 sec)
  506.  *   and \335 (break signal)
  507.  */
  508. zmputs(s)
  509. char *s;
  510. {
  511.     register c;
  512.  
  513.     while (*s) {
  514.         switch (c = *s++) {
  515.         case '\336':
  516.             sleep(1); continue;
  517.         case '\335':
  518.             sendbrk(); continue;
  519.         default:
  520.             sendline(c);
  521.         }
  522.     }
  523.     flushmo();
  524. }
  525.  
  526.  
  527. /* VARARGS1 */
  528. vfile(f, a, b, c, d)
  529. char *f;
  530. long a, b, c, d;
  531. {
  532.     if (Verbose > 2) {
  533.         fprintf(stderr, f, a, b, c, d);
  534.         fprintf(stderr, "\n");
  535.     }
  536. }
  537.  
  538. /* End of rbsb.c */
  539.